#ifndef BRDF_H
#define BRDF_H
#include "globals.h"
#include "rtcore/rtcore.h"
#include "random.h"
#include "intersection.h"
#include "color.h"
#include "configurable.h"
namespace gemren
{
	
	class bsdf : public configurable
	{
	public:
		virtual ~bsdf(){}
		virtual void bounce(random* ran, const scene* sc, intersection* i)  const = 0;
		virtual void bounce_fast(random* ran, const scene* sc, intersection* i)  const                       { bounce(ran, sc, i); }
		virtual color_s throughput(const coord& incoming, const coord& outcoming, const coord& normal)const  { return color_s(0.0f);  }
		virtual bool is_directly_lighted()  { return false; }
		virtual bool is_light_transmitting(){ return false; }
		virtual bool has_btdf()				{ return false; }
		virtual float pdf(const coord& incoming, const coord& outcoming, const coord& normal) const { return 0.0f; }
	};
	
	class brdf_specular: public bsdf
	{
		color_s color;
		spectrum_dynamic display_color;
	public:
		brdf_specular(): color(1.0f), display_color(1.0f) {}
		virtual void bounce(random* ran, const scene* sc, intersection* i) const;
		virtual bool is_light_transmitting(){return true;}

		virtual void announce_properties(const std::string& prefix, property_announcer announcer);
	protected:
		virtual err_t set_my_string(std::string& name, const std::string& value);
	};

	class brdf_diffuse : public bsdf
	{
	protected:
		color_s color;
		spectrum_dynamic display_color;
	public:
		brdf_diffuse(): color(0.5f), display_color(0.5f){}
		virtual void bounce(random* ran, const scene* sc, intersection* i) const;
		virtual void bounce_fast(random* ran, const scene* sc, intersection* i) const { i->terminate(); }
		virtual color_s throughput(const coord& incoming, const coord& outcoming, const coord& normal)const;
		virtual bool is_directly_lighted() {return true;}
		virtual float pdf(const coord& incoming, const coord& outcoming, const coord& normal) const;
		virtual void announce_properties(const std::string& prefix, property_announcer announcer);
	protected:
		virtual err_t set_my_string(std::string& name, const std::string& value);
	};
	
	class bsdf_fresnel: public bsdf
	{
		refraction_s refr_ind;
		spectrum_dynamic display_refr_ind;
	protected:
		virtual err_t set_my_string(std::string& name, const std::string& value);
	public:
		virtual bool has_btdf() { return true; }
		bsdf_fresnel()
			: refr_ind(1.0f), display_refr_ind(1.0f) {}
		virtual void announce_properties(const std::string& prefix, property_announcer announcer);
		virtual void bounce(random* ran, const scene* sc, intersection* i) const;
		virtual void bounce_fast(random* ran, const scene* sc, intersection* i) const;
		virtual bool is_light_transmitting(){return true;}	
	};

	class btdf_clear: public bsdf
	{//transmittance
	
	public:
		virtual void bounce(random* ran, const scene* sc, intersection* i) const
		{ 
			i->outcoming = i->incoming; i->reflectance = 1.0f; 
		}
		virtual bool is_light_transmitting(){return true;}
		
	};





}

#endif